#include <iostream>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

/*
进程间通信的本质(前提): 让进行通信的两个进程看到同一份公共资源
*/

int main()
{
    int fds[2];
    assert(pipe(fds) == 0);
    pid_t fd = fork();
    if (fd == 0)
    {
        close(fds[0]);
        //子进程 todo
        const char* msg = "hello, I am child";
        int cnt = 0;
        while (true)
        {
            char buffer[1024];
            cnt++;
            ssize_t size = snprintf(buffer, sizeof buffer - 1, "%s[%d]", msg, getpid());
            buffer[size] = '\0';
            size = write(fds[1], buffer, strlen(buffer));
            assert(size == strlen(buffer));
            sleep(2);//1.读快写慢 一次读入一段规则数据
            /*
            close(fds[1]);//3.写端关闭 则需要在读端将管道剩余数据读取完毕后手动关闭读端
            break;
            */
        }
        exit(0);
    }
    close(fds[1]);
    //父进程 todo
    while (true)
    {
        //sleep(2);//2.读慢写快 一次读入大量不规则数据
        char buffer[1024];
        ssize_t size = read(fds[0], buffer, sizeof buffer - 1);
        assert(size != -1);
        /*
        if (size == 0)//3.写端关闭 管道剩余数据读取完毕 手动关闭读端
            break;
        */
        buffer[size] = '\0';
        printf("[%d]getMessage: %s\n", getpid(), buffer);
        /*
        close(fds[0]);//4.读端关闭 os观测到写端还在向管道写入数据 则终止写端进程
        break;
        */
    }
    fd = waitpid(fd, nullptr, 0);
    /*
    int status;
    fd = waitpid(fd, &status, 0);//读端关闭 os强制终止写端进程(子进程) status获取子进程退出信息
    */
    assert(fd != -1);
    //cout << (status & 0x7f) << endl;//获取子进程退出信号(低7位)
    return 0;
}
